import gcu_gpio_reg
from time import sleep
import numpy as np

GPIO_BASE_ADDR = 0x0000_0000
SYS_BASE_ADDR = 0x0000_FF00

def eye_scan(device_ip='192.168.10.10'):
    TAP_NUM = 125#63#

    _gpio_reg = gcu_gpio_reg.Gpio_reg(device_ip)

    _gpio_reg.writereg(SYS_BASE_ADDR, 'F000', '0000')
    bertnp = np.zeros(TAP_NUM)
    for tap in range(TAP_NUM):
        _gpio_reg.writereg(SYS_BASE_ADDR, 'F200', '%04x' % tap)
        _gpio_reg.writereg(SYS_BASE_ADDR, 'F200', '%04x' % (1<<7 | tap))
        _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0002')
        sleep(0.1)
        bert = _gpio_reg.readback(SYS_BASE_ADDR, '7300')
        bertnp[tap] = int(bert.hex(),16)
        tapout = _gpio_reg.readback(SYS_BASE_ADDR, '7100')
        print('tap:%s, bert:%s' % (int(tapout.hex(),16), bert.hex()))


    i = 0
    start0 = 0  # when tap=0, bert=0,need to calculate with end part
    start_eye = 0
    eyewin = 10
    central = 0
    eyewinnew = 0
    while i < 120:
        if bertnp[i] == 0:
            flagbegin = i
            if flagbegin == 0:
                start0 = 1
            while bertnp[i] == 0:
                if(i < 120):
                    i += 1
                else:
                    break
            eyewinnew = i-flagbegin
            if start0 == 1:
                start_eye = eyewinnew
                start0 = 0
            if eyewin < eyewinnew:
                eyewin = eyewinnew
                central = (flagbegin+i)//2
        else:
            i += 1
    if bertnp[i] == 0:
        end_eye = eyewinnew
        eyewinnew = end_eye+start_eye
    if eyewin < eyewinnew:
        eyewin = eyewinnew
        if start_eye > end_eye:
            central = (start_eye - end_eye) // 2
        else:
            central = 120 - (end_eye - start_eye) // 2

    if(central == 0):
        print("eye is too narrow")
    _gpio_reg.writereg(SYS_BASE_ADDR, 'F200', '%04x' % central)
    _gpio_reg.writereg(SYS_BASE_ADDR, 'F200', '%04x' % (1<<7 | central))

    print("GCU:", end=' ')
    print(device_ip, end='\t')
    _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0002')
    _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0000')
    # lol = _gpio_reg.readback(SYS_BASE_ADDR, '7200')
    # bert = _gpio_reg.readback(SYS_BASE_ADDR, '7300')
    # ecode = _gpio_reg.readback(SYS_BASE_ADDR, '7F00')
    print('eyewin: %d, central:%d' % (eyewin, central))
    # sleep(2)
    return eyewin
    # with open('tapcnt.txt', "a") as raw_file:
    #     raw_file.write('%04d\n' % central[b])

def error_check():
    device_ip = '192.168.10.10'
    _gpio_reg = gcu_gpio_reg.Gpio_reg(device_ip)
    # _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0001')
    _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0000')

    #sleep(1)
    lol = _gpio_reg.readback(SYS_BASE_ADDR, '7200')
    bert = _gpio_reg.readback(SYS_BASE_ADDR, '7300')

    ecode = _gpio_reg.readback(SYS_BASE_ADDR, '7F00')
    print(ecode.hex())
    retry = 0
    while(ecode.hex()[4] == '0' and retry < 0):  #ddr test error
        print(retry)
        _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0005')
        sleep(2)
        _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0004')
        sleep(1)
        _gpio_reg.writereg(SYS_BASE_ADDR, 'F100', '0000')
        sleep(6)
        ecode = _gpio_reg.readback(SYS_BASE_ADDR, '7F00')
        print(ecode.hex())
        retry = retry + 1

    print('lol:%s, bert:%s, ecode:%s' % (lol.hex(), bert.hex(), ecode.hex()))
    return int(lol.hex(), base=16),int(bert.hex(), base=16),int(ecode.hex(), base=16)

def main():
    # eye_scan()
    error_check()

if __name__ == "__main__":
    main()
